﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using Economic.Api.Client;
using Economic.Api.Data;
using Economic.Api.Exceptions;

namespace TireService.Data
{
    public class CustomerBLL
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="db"></param>
        /// <param name="customer"></param>
        /// <param name="CustomerId"></param>
        /// <param name="ParentCompany"></param>
        /// <param name="ParentCustomerId"></param>
        /// <param name="ParentPayInvoice"></param>
        /// <param name="IsCompany"></param>
        /// <param name="CompanyName"></param>
        /// <param name="CompanyNumber"></param>
        /// <param name="Name"></param>
        /// <param name="Address"></param>
        /// <param name="ZipCode"></param>
        /// <param name="City"></param>
        /// <param name="CountryId"></param>
        /// <param name="SecondaryAddress"></param>
        /// <param name="SecondaryZipCode"></param>
        /// <param name="SecondaryCity"></param>
        /// <param name="Phone1"></param>
        /// <param name="Phone1Type"></param>
        /// <param name="Phone2"></param>
        /// <param name="Phone2Type"></param>
        /// <param name="Email"></param>
        /// <param name="OnPrimaryAddressInPrimeTime"></param>
        /// <param name="SyncToEconomic"></param>
        /// <param name="ManualInvoicing"></param>
        /// <param name="InvoicePBS"></param>
        /// <param name="SubmitInTransaction"></param>
        public Customer UpdateCustomer(TireServiceDB db, Customer customer, int CustomerId, bool ParentCompany, int? ParentCustomerId, bool ParentPayInvoice, bool IsCompany, string CompanyName, string CompanyNumber, string Name, string Address, string ZipCode, string City, int CountryId, string SecondaryAddress, string SecondaryZipCode, string SecondaryCity, string Phone1, int Phone1Type, string Phone2, int? Phone2Type, string Email, bool OnPrimaryAddressInPrimeTime, bool SyncToEconomic, bool ManualInvoicing, bool InvoicePBS, bool SubmitInTransaction)
        {
            try
            {
                // Create/Update existing customer
                if (CustomerId != 0)
                {
                    customer = db.GetCustomer(CustomerId);

                    if (ParentPayInvoice != customer.ParentPayInvoice)
                    {
                        throw new ArgumentException("Ændring af faktura betaler kan IKKE udføres - skal gøres af system administrator manuelt.");
                    }

                    if (SyncToEconomic != customer.SyncToEconomic)
                    {
                        throw new ArgumentException("Ændring af synkronisering med E-conomic kan IKKE udføres - skal gøres af system administrator manuelt.");
                    }
                }

                if (ParentCompany)
                {
                    customer.ParentCustomerId = Convert.ToInt32(ParentCustomerId);
                    customer.ParentPayInvoice = ParentPayInvoice;
                }

                customer.IsCompany = IsCompany;

                if (IsCompany)
                {
                    customer.CompanyName = CompanyName;
                    customer.CompanyNumber = CompanyNumber;
                }

                customer.Name = Name;
                customer.Address = Address;
                customer.ZipCode = ZipCode;
                customer.City = City;
                customer.CountryId = CountryId;

                // Calculate longitude and latitude for address
                try
                {
                    string primaryAddress = Address + ", " + ZipCode + " " + City + ", " + db.GetCountryName(customer.CountryId);
                    GoogleMaps googleMapAPI = new GoogleMaps(ConfigurationSettings.AppSettings["MapKey"]);
                    double[] LongLatPrimary = googleMapAPI.GetLongLatCoordinates(primaryAddress);
                    customer.LongitudePrimary = LongLatPrimary[0];
                    customer.LatitudePrimary = LongLatPrimary[1];
                }
                catch (Exception)
                {
                    // Error calculating longitude and latitude - values will be set to null
                }


                if (SecondaryAddress != "") customer.SecondaryAddress = SecondaryAddress;
                if (SecondaryZipCode != "") customer.SecondaryZipCode = SecondaryZipCode;
                if (SecondaryCity != "") customer.SecondaryCity = SecondaryCity;
                if (SecondaryAddress != "" & SecondaryZipCode != "" & SecondaryCity != "")
                {
                    // Calculate longitude and latitude for secondary address
                    try
                    {
                        string secondaryAddress = SecondaryAddress + ", " + SecondaryZipCode + " " + SecondaryCity + ", " + db.GetCountryName(customer.CountryId);
                        GoogleMaps googleMapAPI = new GoogleMaps(ConfigurationSettings.AppSettings["MapKey"]);
                        double[] LongLatSecondary = googleMapAPI.GetLongLatCoordinates(secondaryAddress);
                        customer.LongitudeSecondary = LongLatSecondary[0];
                        customer.LatitudeSecondary = LongLatSecondary[1];
                    }
                    catch (Exception)
                    {
                        // Error calculating longitude and latitude - values will be set to null
                    }

                }
                else
                {
                    customer.LongitudeSecondary = null;
                    customer.LatitudeSecondary = null;
                }

                customer.Phone1 = Phone1;
                customer.Phone1Type = Convert.ToInt32(Phone1Type);
                //if (Phone2 != null | Phone2Type != null)
                //{
                //    customer.Phone2 = Phone2.ToString();
                //    customer.Phone2Type = Convert.ToInt32(Phone2Type);    
                //}
                if (Phone2 != "") customer.Phone2 = Phone2;
                if (Phone2 != "") customer.Phone2Type = Convert.ToInt32(Phone2Type);    
                
                customer.Email = Email;
                customer.OnPrimaryAddressInPrimeTime = OnPrimaryAddressInPrimeTime;
                customer.SyncToEconomic = SyncToEconomic;

                // Create new customer
                if (customer.CustomerId == 0)
                {
                    db.AddCustomer(customer);
                }

                // Check if customer is being created/updated in other transaction
                if (!SubmitInTransaction)
                {
                    // Submit changes to database
                    db.SubmitChanges();

                    // Update customer in E-conomic
                    EconomicInterface ecoInterface = new EconomicInterface();

                    if (CustomerId == 0 & customer.SyncToEconomic)
                    {
                        // Create debtor in E-conomic
                        ecoInterface.CreateDebtor(customer, db);
                    }
                    else
                    {
                        if (customer.SyncToEconomic)
                        {
                            // Update debtor in E-conomic
                            ecoInterface.UpdateDebtor(customer, db);    
                        }
                    }
                }

                return customer;
            }
            catch (Exception ex)
            {

                return null;
            }
        }

        /// <summary>
        /// Function for identifying the CustomerId that must pay invoice
        /// </summary>
        /// <param name="db">Connection to database</param>
        /// <param name="CustomerId">Id on customer that is checked if that is the highest level of the paying hieraki</param>
        /// <returns>Integer with CustomerId that pays</returns>
        public int GetPayingCustomerId(TireServiceDB db, int CustomerId)
        {
            Customer customer = db.GetCustomer(CustomerId);

            int customerid;

            if (customer.ParentPayInvoice)
            {
                if (customer.ParentCustomerId == null)
                {
                    throw new ArgumentException("Fejl i kunder masterdata - kunde oprettet til at hovedafdeling betaler, men ingen hovedafdeling oprettet på kunde.");
                }
                else
                {
                    customerid = GetPayingCustomerId(db, Convert.ToInt32(customer.ParentCustomerId));
                }
            }
            else
            {
                customerid = customer.CustomerId;
            }

            return customerid;
        }

        public bool FindCustomerIdInHieraki(TireServiceDB db, int FindCustomerId, int ParentCustomerId)
        {
            Customer parentcustomer = db.GetCustomer(ParentCustomerId);

            bool CustomerFound = false;

            if (parentcustomer.ParentCustomerId == null)
            {
                CustomerFound = false;
            }
            else
            {
                if (Convert.ToInt32(parentcustomer.ParentCustomerId) == FindCustomerId)
                {
                    CustomerFound = true;
                }
                else
                {
                    CustomerFound = FindCustomerIdInHieraki(db, FindCustomerId, Convert.ToInt32(parentcustomer.ParentCustomerId));
                }
            }

            return CustomerFound;
        }

        ///// <summary>
        ///// Helper function that returns longitude and latitude coordinates for a specific address from google maps 
        ///// </summary>
        ///// <param name="Address">Address to return coordinates for</param>
        ///// <param name="MapKey">Google Maps API key</param>
        ///// <returns>Double array with longitude and latitude</returns>
        //public static double[] GetLongLatCoordinates(string Address, string MapKey)
        //{
        //    double[] LongLatCoordinates = new double[2];
            
        //    //Shared googleMapAPI = new Shared()
        //    GoogleMaps googleMapAPI = new GoogleMaps(MapKey);
            
        //    LatLng latlng = googleMapAPI.GetLatLng(Address);
        //    LongLatCoordinates[0] = latlng.Longitude / 10000000;
        //    LongLatCoordinates[1] = latlng.Latitude / 10000000;

        //    return LongLatCoordinates;
        //}
    }    
}
